package com.demo.codec;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

import java.util.concurrent.TimeUnit;


/**
 * @author gy
 * @date 2022/5/30
 * 1、我们自定义一个Handler，需要继承 netty 规定好的 某个 HandlerAdapter（规范）
 * 2、这时我们自定义一个Handler，才能称为一个 handler
 *
 * 非当前 Reactor 线程调用 Channel 的各种方法
 *   例如在推送系统的业务线程里面，根据用户的标识，找到对应的 Channel引用，
 *   然后调用 Write类方法向该用户推送消息，就会进入到这种场景。最终的Write会提交到
 *   任务队列中后被异步消费
 */
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
    /**
     * 读取数据 实际（这里我们可以读取客户端发送的消息）
     * @param ctx 上下文对象，含有 管道 pipeLine，通道channel，地址
     * @param msg 就是客户端发送的数据，默认为 object
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        // 读取从客户端发送的StudentPojo.Student
        StudentPOJO.Student student = (StudentPOJO.Student) msg;

        System.out.println("客户端发送的数据 id= " + student.getId() + "名字= " + student.getName());

    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        /**
         * 1、writeAndFlush 是 write + flush
         * 2、将数据写入到缓存，并刷新
         * 3、一般讲，我们对这个发送的数据进行编码
         */
        ctx.writeAndFlush(Unpooled.copiedBuffer("hello, 客户端~ 111",CharsetUtil.UTF_8));
    }

    /**
     * 处理异常，一般是需要关闭通道
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }
}
